﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Data;
using System.Data.OleDb;
using libConn;

namespace ApartmentSale
{
	public partial class DepositEdit : Window
	{
		public DepositEdit()
		{
			this.InitializeComponent();

            gData = new DepositView();
            receipt = new ReceiptView();
            receipt.receipt_type = 1;

            opCommand = OpCommand.CREATE;
		}

        public DepositEdit(ApartmentView apartment)
            :this()
        {
            cbApartmentCode.IsEnabled = false;
            gData.deposit_apartment_code = apartment.apartment_code;

            opCommand = OpCommand.CREATE_BY_APARTMENT_CODE;
        }

        public DepositEdit(DepositView data)
            :this()
        {
            this.Title = "View deposit information";
            gData = data;
            opCommand = OpCommand.UPDATE;


            tbReceiptCode.IsEnabled = false;
            if (data.deposit_status != 1)
            {
                cbStatus.IsEnabled = true;
                cbApartmentCode.IsEnabled = false;
            }
            else
            {
                tbReceiptCode.IsEnabled = false;
                cbApartmentCode.IsEnabled = false;
            }

            tbReceiptCode.Text = data.receipt_code;
            cbStatus.SelectedIndex = data.deposit_status;
            tbAmount.Text = data.deposit_amount.ToString();

            tbName.Text = data.deposit_custom_name;
            tbContact.Text = data.deposit_custom_contact;

            orStatus = data.deposit_status;

            getReceipt();

            tbCash.Text = String.Format("{0:N2}", receipt.receipt_cash_amount);
            tbCard.Text = String.Format("{0:N2}", receipt.receipt_card_amount);
            tbCheck.Text = String.Format("{0:N2}", receipt.receipt_check_amount);
            tbAmount.Text = String.Format("{0:N2}", receipt.receipt_amount);
        }

        private DepositView gData;
        private ReceiptView receipt;
        private int orStatus = -1;
        private enum OpCommand { CREATE, UPDATE, CREATE_BY_APARTMENT_CODE }
        private OpCommand opCommand;

        private bool getApartmentCode()
        {
            string errMessage = null;
            string str = "SELECT apartment_code FROM apartments WHERE apartment_status = 0 ORDER BY apartment_code";

            cbApartmentCode.Items.Clear();

            DataTable oleDT;
            oleDT = libConn.AccdbConn.query(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Failed to read the apartment code",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return false;
            }

            if (oleDT.Rows.Count < 1)
            {
                return true;
            }

            foreach (DataRow r in oleDT.Rows)
            {
                cbApartmentCode.Items.Add(r[0]);
            }

            return true;
        }

        private int getApartmentID(String code)
        {
            string errMessage = null;
            string str = "SELECT apartment_id FROM apartments WHERE apartment_code = '"
                + code.Replace("'","''") + "'";

            DataTable oleDT;
            oleDT = libConn.AccdbConn.query(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Failed to read the apartment code",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return -1;
            }

            if (oleDT.Rows.Count < 1)
            {
                return -1;
            }

            return Convert.ToInt32(oleDT.Rows[0][0]);
        }

        private bool checkReceiptCode(string data)
        {
            string errMessage = null;
            string str = "SELECT * FROM receipt WHERE receipt_code = '"
                + data.Replace("'", "''") + "'";

            DataTable oleDT;
            oleDT = libConn.AccdbConn.query(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Failed to read the Receipt SN",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return false;
            }

            if (oleDT.Rows.Count > 0)
            {
                System.Windows.MessageBox.Show(
                    "Exist in the same Receipt SN, please check.",
                    "Save failed",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Stop);
                return false;
            }

            return true;
        }

        private int getReceiptId(string code)
        {
            string errMessage = null;
            string str = "SELECT * FROM receipt WHERE receipt_code = '"
                + code.Replace("'", "''") + "'";

            DataTable oleDT;
            oleDT = libConn.AccdbConn.query(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Failure to obtain a Receipt SN",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return -1;
            }

            if (oleDT.Rows.Count == 0)
            {
                System.Windows.MessageBox.Show(
                    "Can not find the Receipt SN",
                    "Save failed",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Stop);
                return -1;
            }

            return Convert.ToInt32(oleDT.Rows[0][0]);
        }

        private void getReceipt()
        {
            string errMessage = null;
            string str = "SELECT * FROM receipt WHERE receipt_id = "
                + gData.receipt_id;

            DataTable oleDT;
            oleDT = libConn.AccdbConn.query(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Failure to obtain a Receipt SN",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return;
            }

            if (oleDT.Rows.Count == 0)
            {
                System.Windows.MessageBox.Show(
                    "Can not find the Receipt SN",
                    "Save failed",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Stop);
                return;
            }

            DataRow r = oleDT.Rows[0];
            receipt = new ReceiptView(r);
        }

        private bool insertData(DepositView data)
        {
            string errMessage = null;

            string str = "INSERT INTO deposit (deposit_status, receipt_id, receipt_code, deposit_amount, deposit_apartment_code, deposit_custom_name, deposit_custom_contact, deposit_create_date, apartment_id) VALUES (";
            str += data.deposit_status + ", ";
            str += data.receipt_id + ", '";
            str += data.receipt_code.Replace("'", "''") + "', ";
            str += data.deposit_amount + ",'";
            str += data.deposit_apartment_code.Replace("'", "''") + "', '";
            str += data.deposit_custom_name.Replace("'", "''") + "', '";
            str += data.deposit_custom_contact.Replace("'", "''") + "', '";
            str += DateTime.Now.ToString() + "', ";
            str += data.apartment_id + ")";

            libConn.AccdbConn.exec(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Save deposit data failed",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return false;
            }

            str = "UPDATE apartments SET apartment_status = 1 WHERE apartment_code = '" + data.deposit_apartment_code + "'";

            libConn.AccdbConn.exec(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Save deposit data failed",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return false;
            }

            MessageBox.Show("Add deposit records success");
            return true;
        }

        private bool updateData(DepositView data)
        {
            string errMessage = null;

            string str = "UPDATE deposit SET deposit_status = " + data.deposit_status + ", ";
            str += "receipt_id = " + data.receipt_id + ", ";
            str += "receipt_code = '" + data.receipt_code + "', ";
            str += "deposit_amount = " + data.deposit_amount + ", ";
            str += "deposit_apartment_code = '" + data.deposit_apartment_code.Replace("'", "''") + "', ";
            str += "deposit_custom_name = '" + data.deposit_custom_name.Replace("'", "''") + "', ";
            str += "deposit_custom_contact = '" + data.deposit_custom_contact.Replace("'", "''") + "', ";
            str += "deposit_modify_date = '" + DateTime.Now.ToString() + "', ";
            str += "apartment_id = " + data.apartment_id + " ";
            str += "WHERE deposit_id = " + data.deposit_id;

            libConn.AccdbConn.exec(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Failed to modify the deposit",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return false;
            }

            if (data.deposit_status != orStatus)
            {
                int apartment_status = 0;
                if (orStatus == 0)
                {
                    apartment_status = 0;
                }
                else
                {
                    if (data.deposit_status == 2 || data.deposit_status == 3)
                    {
                        MessageBox.Show("Modify the deposit data successfully.");
                        return true;
                    }
                    apartment_status = 1;
                }

                str = "UPDATE apartments SET apartment_status = " +
                    apartment_status.ToString() + " WHERE apartment_code = '" + data.deposit_apartment_code + "'";

                libConn.AccdbConn.exec(str, ref errMessage);

                if (errMessage != null)
                {
                    System.Windows.MessageBox.Show(
                        errMessage,
                        "Failed to modify the deposit",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                    return false;
                }
            }

            MessageBox.Show("Modify the deposit data successfully.");
            return true;
        }

        private void btSave_Click(object sender, RoutedEventArgs e)
        {
            if (tbReceiptCode.Text.Length == 0)
            {
                MessageBox.Show("Please enter the Receipt SN.");
                tbReceiptCode.Focus();
                return;
            }

            gData.receipt_code = tbReceiptCode.Text;
            receipt.receipt_code = tbReceiptCode.Text;

            if (gData.deposit_status != 1 && cbStatus.SelectedIndex == 1)
            {
                MessageBox.Show("The state can not be manually changed to 'Cancel Out'.");
                cbStatus.SelectedIndex = gData.deposit_status;
                cbStatus.Focus();
                return;
            }

            gData.deposit_status = cbStatus.SelectedIndex;
            receipt.receipt_status = cbStatus.SelectedIndex;

            if (cbApartmentCode.SelectedIndex == -1)
            {
                MessageBox.Show("Apartment code is not selected, or entered the wrong code, please check.");
                cbApartmentCode.Focus();
                return;
            }

            gData.deposit_apartment_code = cbApartmentCode.SelectedItem.ToString();
            gData.apartment_id = getApartmentID(gData.deposit_apartment_code);
            receipt.apartment_id = gData.apartment_id;
            if (gData.apartment_id == -1)
                return;

            double amount;
            if (tbAmount.Text.Length == 0 || !Double.TryParse(tbAmount.Text, out amount) || amount < 0)
            {
                MessageBox.Show("Please enter the correct amount.");
                tbAmount.Focus();
                return;
            }

            gData.deposit_amount = receipt.receipt_amount;

            gData.deposit_custom_name = tbName.Text;
            gData.deposit_custom_contact = tbContact.Text;

            receipt.receipt_custom_name = tbName.Text;

            if (opCommand == OpCommand.CREATE || opCommand == OpCommand.CREATE_BY_APARTMENT_CODE)
            {
                if (!checkReceiptCode(gData.receipt_code))
                    return;

                string errMessage;
                errMessage = receipt.Insert();

                if (errMessage != "")
                {
                    MessageBox.Show(errMessage, "Save failed", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                gData.receipt_id = getReceiptId(gData.receipt_code);
                if (gData.receipt_id == -1)
                    return;

                if (insertData(gData))
                    this.Close();
            }
            else
            {
                string errMessage;
                errMessage = receipt.Update();

                if (errMessage != "")
                {
                    MessageBox.Show(errMessage, "Save failed", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                if (updateData(gData))
                    this.Close();
            }
        }

        private void btClose_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (!getApartmentCode())
                this.Close();

            if (opCommand == OpCommand.UPDATE || opCommand == OpCommand.CREATE_BY_APARTMENT_CODE)
            {
                cbApartmentCode.Items.Add(gData.deposit_apartment_code);
                cbApartmentCode.SelectedItem = gData.deposit_apartment_code;
            }
        }

        private void AmountChanged(object sender, RoutedEventArgs e)
        {
            double d;
            TextBox c = sender as TextBox;
            if (c != null)
            {
                if (!Double.TryParse(c.Text, out d))
                {
                    c.Text = "0.00";
                }
                else
                {
                    c.Text = String.Format("{0:N2}", d);
                }
            }
            else
            {
                return;
            }

            double cash;
            double card;
            double check;

            if (Double.TryParse(tbCash.Text, out cash) &&
                Double.TryParse(tbCard.Text, out card) &&
                Double.TryParse(tbCheck.Text, out check))
            {
                receipt.receipt_cash_amount = cash;
                receipt.receipt_card_amount = card;
                receipt.receipt_check_amount = check;
                receipt.receipt_amount = cash + card + check;

                tbAmount.Text = String.Format("{0:N2}", receipt.receipt_amount);
            }
        }
	}
}